home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char RCSid[] = "$Header: QD:ups/ups2/RCS/upsd.c,v 1.4 1986/11/19 15:21:52 scooter Exp alph $";
- #endif
-
- /*
- * upsd - package delivery server
- *
- * upsd is the program that is called by inetd when a ups
- * request is issued. It will read and write to standard input
- * and standard output. Here is a description of the ups
- * protocol:
- *
- * ups upsd type
- *
- * user_name ------> login name of package receiver String
- * from_name ------> login name of package sender String
- * full_name ------> full name of package sender String
- * message ------> mail message to send String
- * <----- 0 for OK Byte
- * For each file:
- * file_name ------> name of file to be delivered String
- * file_size ------> size of file in bytes Long
- * <----- 0 for OK Byte
- * file ------> file size bytes
- * <----- 0 for OK Byte
- * file_mode ------> file mode Int
- * <----- 0 for OK Byte
- *
- * When its all done:
- * complete ------> We're done ('-Done-') String
- * <----- 0 for OK Byte
- *
- * $Author: scooter $
- * $Revision: 1.4 $
- * $Date: 1986/11/19 15:21:52 $
- *
- * $Log: upsd.c,v $
- * Revision 1.4 86/11/19 15:21:52 scooter
- * Changed error severity level from ERR to INFO
- *
- * Revision 1.3 86/09/19 18:53:37 scooter
- * Added -i option for mail specification.
- * Also added syslog stuff.
- *
- * Revision 1.2 85/08/21 22:28:11 scooter
- * Release revision: added more complete RCS headers.
- *
- *
- */
-
- #ifdef amigados
- #include "sys.h"
- #endif
-
- #include <stdio.h>
- #include <pwd.h>
- #include <grp.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <syslog.h>
- #include <string.h>
-
- #ifndef amigados
- long atol();
- int atoi();
- #else
- #include <popen.h>
- #include "upsd_protos.h"
- #endif
-
- char buffer[BUFSIZ*5]; /* character input buffer */
- char file_name[BUFSIZ]; /* file name */
- char file_path[BUFSIZ]; /* full path to destination */
- #ifdef amigados
- char file_path2[BUFSIZ]; /* full path to destination */
- #endif
- char user_name[BUFSIZ]; /* Receiver name */
- char from_name[BUFSIZ]; /* Sender name */
- char full_name[BUFSIZ]; /* Full name of sender */
- char file_list[BUFSIZ]; /* List of all files */
- long file_size; /* number of bytes in file */
- int file_mode; /* mode of the file */
- char mail_message[BUFSIZ*4]; /* mail message */
- int mcount; /* number of characters in mail buffer */
-
- int fid; /* File descriptor for destination */
- #ifdef DEBUG
- int debugflag = 1; /* Debug flag */
- #else
- int debugflag = 0; /* Debug flag */
- #endif
-
- #ifdef amigados
- extern int server_socket;
- extern int errno;
- #endif
-
- int fdin, fdout;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *ptr,*tptr,*mptr;
- int f, i, file;
- struct sockaddr_in sin;
- struct hostent *peer;
- struct passwd *pwent;
- int retries = 10;
-
- #ifndef amigados
- fdinout = 0;
- fdout = 1;
- #else
- fdin = server_socket + S_MAXFH; /* s_socket magic */
- fdout = fdin;
- #endif
-
- openlog("upsd",LOG_ODELAY,LOG_DAEMON);
-
- syslog(LOG_DEBUG, "started - test");
-
- if(argc>1 && !strcmp(argv[1], "-d") )
- debugflag++;
-
- if (debugflag)
- syslog(LOG_DEBUG,"started");
-
- i = sizeof (sin);
- if (getpeername(fdin, &sin, &i) < 0)
- syslog(LOG_ERR,"getpeername failed: %m");
-
- if (debugflag)
- syslog(LOG_DEBUG,"Calling gethostbyaddr");
-
- peer = gethostbyaddr((char *)&sin.sin_addr,
- sizeof(sin.sin_addr),sin.sin_family);
-
- buffer[0] = '\0';
- file_list[0] = '\0';
-
- if (debugflag)
- syslog(LOG_DEBUG,"Reading first buffer");
-
- read(fdin, buffer, BUFSIZ*5); /* fetch receiver and sender names */
-
- if (debugflag)
- syslog(LOG_DEBUG,"receiver/sender/message: %s",buffer);
-
- ptr = buffer;
- while (*ptr != '\n')
- ptr++;
- *ptr++ = NULL;
- strcpy(user_name, buffer); /* save receiver name */
- tptr = ptr;
- while (*tptr != '\n')
- tptr++;
- *tptr++ = NULL;
- strcpy(from_name, ptr); /* save sender name */
- mptr = tptr;
- while ((*mptr != '\n') && (*mptr != '\0'))
- mptr++;
- *mptr++ = NULL;
- strcpy (full_name, tptr); /* save sender's full name */
- strcpy (mail_message, mptr); /* save the mail message */
-
- /*
- * Check for a valid user
- */
- #ifdef amigados
- if(1)
- {
- char *env;
-
- #if 1 /* deactivate this to become schizophrenic :-) */
- env = getenv("UPS_USERS");
- if(!env)
- {
- error("Receiver name", "UPS_USERS not set");
- exit(1);
- }
- {
- int l = strlen(user_name);
- char *s;
- int legal=0;
-
- while(s = strstr(env, user_name))
- {
- if(((s == env) || (*(s-1) == ':'))
- && ((s[l] == '\0') || (s[l] == ':')))
- {
- legal = 1;
- break;
- }
- }
- if(!legal)
- {
- error("Receiver name, Not in UPS_USERS:", user_name);
- exit(1);
- }
- }
- #endif
- /* fake password entry */
- pwent = malloc(sizeof(struct passwd));
- memset(pwent, 0, sizeof(struct passwd));
- pwent->pw_passwd = strdup("");
- pwent->pw_shell = strdup("");
- pwent->pw_name = strdup(user_name);
- pwent->pw_gecos = strdup("Amiga OS Power User");
-
- ack();
- }
- #else
- if ((pwent = getpwnam(user_name)))
- ack();
- else
- {
- error("Receiver name","No such person");
- exit(1);
- }
- #endif
- mcount = strlen (mail_message);
- if (debugflag)
- syslog(LOG_DEBUG,"mail message (%d chars):\n %s", mcount, mail_message);
-
- for (file = 0 ;;)
- {
- #ifdef amigados
- int cnt;
- #endif
- if ((cnt = read(fdin, buffer, BUFSIZ)) <= 0) {
- error("file name","premature EOF or file read error");
- if (debugflag)
- syslog(LOG_DEBUG,"cnt = %d, errno = %d", cnt, errno);
- #ifdef amigados
- if(--retries)
- {
- error("file name", "too many retries");
- break;
- }
- continue;
- }
- #ifdef amigados
- retries = 10;
- #endif
- strcpy(file_name,buffer);
-
- if (debugflag)
- syslog(LOG_DEBUG,"File name:%s",file_name);
-
-
- /*
- * Are we done??
- */
- if (!strncmp(file_name,"-Done-",6)) break;
-
- if ( (fid = opendest(user_name,file_name,
- pwent->pw_uid,pwent->pw_gid)) <= 0 )
- {
- continue;
- }
- ack();
-
- if (read(fdin, buffer, BUFSIZ) <= 0) {
- error("file size","premature EOF or file read error");
- if (debugflag)
- syslog(LOG_DEBUG,"errno = %d", errno);
- continue;
- }
-
- file_size = atol(buffer); /* get number of bytes */
- ack();
-
- copyfile(&file);
-
- if (read(fdin, buffer, BUFSIZ) <= 0) {
- error("file mode","premature EOF or file read error");
- continue;
- }
- file_mode = atoi(buffer); /* get the file mode */
- #ifndef amigados
- file_mode &= 0700; /* Strip the low order modes */
- #else
- /* use unix style modes for transmission to be compatible with
- unix version, we will loose amiga specific bits */
- {
- int ami_mode = 8; /* read per default on */
-
- if(file_mode & 0444)
- ami_mode |= 8;
- if(file_mode & 0222)
- ami_mode |= 4 | 1;
- if(file_mode & 0111)
- ami_mode |= 2;
- file_mode = ami_mode;
- }
- #endif
- if (chmod(file_path,file_mode)) {
- error("file mode","chmod failed");
- continue;
- }
- ack();
- #ifndef amigados
- chown(file_path,pwent->pw_uid,pwent->pw_gid);
- #endif
-
- }
- ack();
-
- if (file)
- sendmail(from_name,full_name,peer->h_name,
- user_name,file_list,file++,mail_message,mcount);
- }
-
- /*
- copyfile
- copyfile will copy file_size many bytes from stdin to a temporarily created
- file. The filename will be passed back via buffer.
- */
-
- copyfile(file)
- int *file;
- {
- long cnt; /* file size counter */
- int i;
-
- cnt = file_size; /* count down input bytes */
- while (cnt > 0) {
- i = read(fdin, buffer, BUFSIZ);
- write(fid, buffer, i);
- cnt -= i;
- }
- close(fid);
-
- ack();
- sprintf(buffer,"%-15s",file_name);
- if (*file%4)
- strcat(file_list," ");
- else
- strcat(file_list,"\n\t");
-
- (*file)++;
- strcat(file_list,buffer);
- }
-
- /*
- error(option, string)
- char *option, *string;
- This routine is called when some error condition has been encountered.
- option contains an identifier message, while string contains the actual
- error message. Before message is printed, a non-null character is output
- first, then the string error message.
- */
-
- error(option, string)
- char *option, *string;
- {
- char buf[BUFSIZ];
-
-
- buf[0] = 1;
- write(fdout, buf, 1); /* nak */
- sprintf(buf, "upsd: %s: %s\n", option, string);
- write(fdout, buf, strlen(buf)+1);
-
- syslog(LOG_INFO,"error - %s",buf);
- }
-
-
-
- /*
- * ack()
- * This routine is called to return an OK to the remote host.
- */
-
- ack()
- {
- buffer[0] = 0;
- write(fdout,buffer,1);
- }
-
-
-
- /*
- * opendest(name,file)
- * char *name,*file;
- *
- * Open the destination file "file" in UPSDIR/user, creating the
- * file if necessary.
- */
-
- int
- opendest(name,file,uid,gid)
- char *name,*file;
- int uid,gid;
- {
- int ret;
-
- #ifndef amigados
- sprintf(file_path,"%s/%s",UPSDIR,name); /* Form path to directory */
- #else
- strmfp(file_path,UPSDIR,name); /* Form path to directory */
- #endif
-
- if (access(file_path,F_OK) == (-1))
- {
- #ifndef amigados
- mkdir(file_path,0700);
- chown(file_path,uid,gid);
- #else
- mkdir(file_path);
- #endif
- }
-
- #ifndef amigados
- sprintf(file_path,"%s/%s/%s",UPSDIR,name,file);
- #else
- strcpy(file_path2, file_path);
- sprintf(file_path,"%s/%s",file_path2,file);
- #endif
-
- if (!access(file_path,F_OK))
- {
- error("file creation","A file by that name has already been sent to that user.");
- return(0);
- } else {
- #ifndef amigados
- ret = open(file_path,O_WRONLY|O_CREAT,0600);
- #else
- ret = open(file_path,O_WRONLY|O_CREAT);
- #endif
- if (ret <= 0)
- {
- sprintf(buffer,"unable to open destination file: %s",
- file_path);
- error("file open",buffer);
- return(0);
- }
- return(ret);
- }
- }
-
-
-
- /*
- * sendmail(from,full,from_host,to,list,mess,count)
- * char *from,*full,*to,*from_host,*list,*mess;
- * int count;
- *
- * This routine sends mail to the destination user to inform
- * them that ups files are awaiting them.
- */
-
- sendmail(from,full,from_host,to,list,file,mess,count)
- char *from,*full,*to,*from_host,*list,*mess;
- int file,count;
- {
- FILE *send,*popen();
- static char myhost[BUFSIZ];
-
- #ifndef amigados
- gethostname(myhost,BUFSIZ);
- #else
- if(1)
- {
- char *env;
-
- env = getenv("HOSTNAME");
- if(env)
- strncpy(myhost, env, BUFSIZ);
- else
- strncpy(myhost, "HOSTNAME not set", BUFSIZ);
- }
- #endif
- sprintf(buffer,"%s -f%s@%s -F\"%s\" -t",SENDMAIL,from,from_host,full);
-
- if(debugflag)
- syslog(LOG_DEBUG,"sendmail\n%s",buffer);
-
- send = popen(buffer,"w");
-
- fprintf(send,"To: %s@%s\n",to,myhost);
-
- if(debugflag)
- syslog(LOG_DEBUG,"To: %s@%s",to,myhost);
-
- fprintf(send,"Subject: UPS delivery\n");
- if (file > 1)
- strcpy(buffer,"files");
- else
- strcpy(buffer,"file");
-
- fprintf(send,"I have sent you the following %s using ups:\n",buffer);
- fprintf(send,"%s\n\n",list);
- if (file > 1)
- strcpy(buffer,"these files");
- else
- strcpy(buffer,"this file");
-
- fprintf(send,"To retrieve %s, use the ups command.\n\n\n",buffer);
- if (count)
- fprintf(send,"%s\n",mess);
- else
- fprintf(send,"\n\n\n\n---ups\n");
- pclose(send);
- }
-